<template>
  <div ref="element" class="panel-container">
    <teleport
      v-for="{ id, type, element } in componentInstances"
      :key="id"
      :to="element"
    >
      <component
        :is="type"
        @maxmized="onMaxmized(type)"
        @minimized="onMinimized(type)"
      ></component>
    </teleport>
  </div>
</template>
<script lang="ts">
/* eslint-disable @typescript-eslint/no-var-requires */
import { useGoldenLayout } from 'src/utils/goldenlayout';
import { defineComponent, ref, nextTick } from 'vue';
import Player from 'components/video/VideoPlayer.vue';
import Chat from './ChatPanel.vue';
import Audio from './AudioPanel.vue';
import Related from './RelatedPanel.vue';
import Captions from './CaptionsPanel.vue';
import Playlist from './PlaylistPanel.vue';
import { useI18n } from 'vue-i18n';
import 'golden-layout/dist/css/goldenlayout-base.css';
import 'golden-layout/dist/css/themes/goldenlayout-dark-theme.css';

const components = {
  Player,
  Chat,
  Audio,
  Related,
  Captions,
  Playlist,
};

export default defineComponent({
  components,
  setup(props, { emit }) {
    const { t } = useI18n();
    interface ComponentInstance {
      id: number;
      type: string;
      element: HTMLElement;
    }
    let instanceId = 0;
    const componentTypes = new Set(Object.keys(components));
    const componentInstances = ref<ComponentInstance[]>([]);

    const createComponent = (type: string, element: HTMLElement) => {
      if (!componentTypes.has(type)) {
        throw new Error(`Component not found: '${type}'`);
      }
      ++instanceId;
      componentInstances.value = componentInstances.value.concat({
        id: instanceId,
        type,
        element,
      });
    };
    const destroyComponent = (toBeRemoved: HTMLElement) => {
      componentInstances.value = componentInstances.value.filter(
        ({ element }) => element !== toBeRemoved
      );
    };
    // Goldenlayout Settings
    const { element, layout } = useGoldenLayout(
      createComponent,
      destroyComponent,
      {
        settings: {
          showCloseIcon: true,
          showMaximiseIcon: false,
          showPopoutIcon: false,
        },
        dimensions: {
          borderWidth: 5,
          headerHeight: 30,
        },
        root: {
          type: 'row',
          content: [
            {
              id: 'player-container',
              type: 'column',
              width: 100,
              content: [
                {
                  id: 'Player',
                  type: 'component',
                  componentType: 'Player',
                  height: 70,
                  isClosable: false,
                  header: {
                    show: false,
                  },
                },
              ],
            },
            {
              type: 'stack',
              width: 30,
              content: [
                {
                  id: 'Audio',
                  type: 'component',
                  componentType: 'Audio',
                  title: t('video.panels.audio.title'),
                },
                {
                  id: 'Playlist',
                  type: 'component',
                  componentType: 'Playlist',
                  title: t('video.panels.playlist.title'),
                },
                {
                  id: 'Chat',
                  type: 'component',
                  componentType: 'Chat',
                  title: t('video.panels.chat.title'),
                },
                {
                  id: 'Related',
                  type: 'component',
                  componentType: 'Related',
                  title: t('video.panels.related.title'),
                },
                {
                  id: 'Captions',
                  type: 'component',
                  componentType: 'Captions',
                  title: t('video.panels.captions.title'),
                },
              ],
            },
          ],
        },
      }
    );
    window.onresize = async () => {
      await doResize();
    };
    const doResize = async () => {
      await nextTick();
      if (layout.value && element.value) {
        layout.value.setSize(
          element.value?.clientWidth,
          element.value?.clientHeight
        );
      }
    };
    function onMaxmized(type: string) {
      if (layout.value) {
        const videoComponent = layout.value.findFirstComponentItemById(type);
        const audioComponent = layout.value.findFirstComponentItemById('Audio');

        if (videoComponent && audioComponent) {
          const videoContainer = videoComponent.parentItem as any;
          const audioContainer = audioComponent.parentItem as any;
          if (videoContainer) {
            if (videoContainer.isMaximised) {
              videoContainer.minimise();
              audioContainer.show();
              emit('minimized');
            } else {
              videoContainer.maximise();
              audioContainer.hide();
              emit('maxmized');
            }
          }
        }
      }
    }
    function onMinimized(type: string) {
      if (layout.value) {
        const videoComponent = layout.value.findFirstComponentItemById(type);
        const audioComponent = layout.value.findFirstComponentItemById('Audio');

        if (videoComponent && audioComponent) {
          const videoContainer = videoComponent.parentItem as any;
          const audioContainer = audioComponent.parentItem as any;
          if (videoContainer) {
            if (videoContainer.isMinimised) {
              videoContainer.maximise();
              audioContainer.show();
              emit('maxmized');
            } else {
              videoContainer.minimise();
              audioContainer.hide();
              emit('minimized');
            }
          }
        }
      }
    }
    function showOrHideComponent(type: string) {
      if (layout.value) {
        const component = layout.value.findFirstComponentItemById(type);
        if (component) {
          console.log(component);
        }
      }
    }
    return {
      element,
      componentInstances,
      doResize,
      onMaxmized,
      onMinimized,
      showOrHideComponent,
    };
  },
});
</script>
<style lang="sass" scoped>

.panel-container
  width: 100%
  height: calc(100vh - 160px)
</style>
